#if !defined(__SYNCHRONISATION_H)
#define __SYNCHRONISATION_H

#include "reseau.h"
#include "emetteur.h"
#include "recepteur.h"
#include "commun/erreur.h"
#include "temps/retour_vers_le_futur.h"
#include "temps/minuterie.h"
#include "temps/chronometre.h"
#include "commun/instantane_du_piano.h"
#include "reseau/client_reseau.h"
#include "reseau/serveur_reseau.h"

/**
 * Exécute un protocole de synchronisation du côté voulu (client ou serveur),
 * lors de l'instanciation.
 * Prérequis :
 *	- le client et le serveur devraient créer une instance de cette classe au
 * même moment dans le temps universel (façon de parler hein), afin que les
 * temps "maintenant" soient ceux référant à ce même moment mais dans les deux
 * référentiels différents. Le meilleur endroit est directement après la connexion.
 *	- une instance de client_reseau ou de serveur_reseau est passée en paramètre
 * du constructeur
 *	- le serveur_reseau doit avoir accepté une connexion, sinon le comportement
 * est indéterminé (référence vers un pointeur nul)
 */
template <class T, int NbAEnvoyer = 200, int TimeOut = 1000>
struct synchronisation {
	enum { nb_a_envoyer = NbAEnvoyer, timeout = TimeOut };
	synchronisation(T &t) throw(erreur);
	float sante_connexion() { return sante_connexion_; }
	double roundtrip_moyen() { return moyenne_roundtrip_; }
	float taux_pertes() { return 1 - sante_connexion(); }
private:
	// sante_connexion_ = 1 - taux_pertes
	// 0 <= sante_connexion_ <= 1
	// NOTE: l'indicateur de santé de la connexion est plus pessimiste chez
	// le serveur que chez le client, puisque chez le client le paquet n'a
	// fait qu'un aller, alors qu'il a fait un aller-retour chez le serveur
	// pour être comptabilisé.
	// On pourrait faire en sorte que les deux parties se transmettent leurs
	// résultats mutuellement par TCP et fassent une moyenne pour avoir quel-
	// que chose de plus crédible.
	float sante_connexion_;
	double moyenne_roundtrip_;
};

#endif
